﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Media.Effects;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Collections;

namespace TouchUmlUI
{
    public class UMLObj : DependencyObject
    {
        public int x;
        public int y;
        public int width;
        public int height;
        public int z_order;
        public GUML guml;
        public System.Windows.Ink.StrokeCollection lines;
        public bool showBackContent = false;

        public virtual Type getType()
        {
            return this.GetType();
        }

        public virtual void showHints(bool a_show)
        {
            Console.WriteLine("UMLObj showAllHints()!");
        }

        public virtual void Refresh()
        {
            Console.WriteLine("UMLObj Refresh()!");
        }

        public virtual void BringToFront()
        {
            guml.canvas.Children.Remove(guml.panel);
            guml.canvas.Children.Add(guml.panel);
        }

        public virtual void swapToBackContent() 
        {
            Console.WriteLine("swapToBackContent - UMLObj");
        }
        public virtual void generateBackContent() 
        {
            Console.WriteLine("generateBackContent - UMLObj");
        }
        public virtual void updateDependencyProperties()
        {
            //Console.WriteLine("updateDependencyPoperties - UMLObj");
            Window1.modified = true;
            SignalR.windowParent.checkModified();            
            ((Diagram.ElementNaDiagramie)guml.obj_uml).polozenie = new System.Drawing.Point((int)InkCanvas.GetLeft(guml.panel),(int)InkCanvas.GetTop(guml.panel));
            ((Diagram.ElementNaDiagramie)guml.obj_uml).rozmiar = new System.Drawing.Size((int)guml.panel.ActualWidth, (int)guml.panel.ActualHeight);            
        }

        public void showControls(bool show, object omit)
        {
            Visibility vis = show == true ? Visibility.Visible : Visibility.Hidden;
            foreach (UIElement elem in guml.panel.Children) {
                if (elem.Equals(omit)) continue;
                elem.Visibility = vis;
            }
        }
        
        public UMLObj(GUML a_arg)
        {
            guml = a_arg;            
        }

        public void setZOrder(int a_arg)
        {
            z_order = a_arg;
        }

        public int getZOrder() { return z_order; }

        public virtual void setX(int ax)
        {
            x = ax;
        }

        public virtual void setY(int ay)
        {
            y = ay;
        }

        public double getX()
        {
            return InkCanvas.GetLeft(this.guml.panel);
        }

        public double getY()
        {
            return InkCanvas.GetTop(this.guml.panel);
        }

        public double getWidth()
        {
            return this.guml.panel.ActualWidth==0?width:this.guml.panel.ActualWidth;
        }

        public double getHeight()
        {
            return this.guml.panel.ActualHeight==0?height:this.guml.panel.ActualHeight;
        }  

        public virtual void setWidth(int a_width)
        {
            width = a_width;
        }
        public virtual void setHeight(int a_height)
        {
            height = a_height;
        }

        public UMLObj Clone()
        {
            if (getType() == typeof(KlasaObj))
            {
                KlasaObj kObj = this as KlasaObj;
                Polozenie p = new Polozenie(kObj.getX(), kObj.getY(), kObj.getWidth(), kObj.getHeight());
                GUML g = SignalR.utworzObiekt(UMLType.CLASS, p, kObj.guml.canvas, kObj.lines, false);
                Random r = new Random();
                ((Diagram.Klasa)g.obj_uml).Nazwa = "Obiekt " + r.Next(0, 666);
                Diagram.Klasa k = kObj.guml.obj_uml as Diagram.Klasa;                
                for (int i = 0; i < k.IloscAtrybutow; i++)
                {
                    Diagram.Atrybut attr = k.GetAtrybut(i);
                    ((Diagram.Klasa)g.obj_uml).DodajAtrybut(attr.Nazwa, attr.Typ.Nazwa);
                }
                for (int i = 0; i < k.IloscOperacji; i++)
                {
                    Diagram.Operacja oper = k.GetOperacje(i);
                    Diagram.Operacja op = ((Diagram.Klasa)g.obj_uml).DodajOperacje(oper.Nazwa, oper.Typ.Nazwa);
                    for (int j = 0; j < op.IloscAtrybutow; j++)
                    {
                        Diagram.Atrybut attr = op.GetAtrybut(j);
                        op.DodajAtrybut(attr);
                    }
                }
                kObj.guml.canvas.Children.Remove(g.panel);
                ((KlasaObj)g.umlobj).Refresh();
                return g.umlobj;
            }
            else if (getType() == typeof(InterfejsObj))
            {
                KlasaObj kObj = this as KlasaObj;
                Polozenie p = new Polozenie(kObj.getX(), kObj.getY(), kObj.getWidth(), kObj.getHeight());
                GUML g = SignalR.utworzObiekt(UMLType.INTERFACE, p, kObj.guml.canvas, kObj.lines, false);
                Random r = new Random();
                ((Diagram.Interfejs)g.obj_uml).Nazwa = "Obiekt " + r.Next(0, 666);
                Diagram.Interfejs k = kObj.guml.obj_uml as Diagram.Interfejs;
                for (int i = 0; i < k.IloscOperacji; i++)
                {
                    Diagram.Operacja oper = k.GetOperacje(i);
                    Diagram.Operacja op = ((Diagram.Interfejs)g.obj_uml).DodajOperacje(oper.Nazwa, oper.Typ.Nazwa);
                    for (int j = 0; j < op.IloscAtrybutow; j++)
                    {
                        Diagram.Atrybut attr = op.GetAtrybut(j);
                        op.DodajAtrybut(attr);
                    }
                }
                kObj.guml.canvas.Children.Remove(g.panel);
                ((KlasaObj)g.umlobj).Refresh();
                return g.umlobj;
            }
            else if (getType() == typeof(NotatkaObj))
            {
                NotatkaObj nObj = this as NotatkaObj;
                Polozenie p = new Polozenie(nObj.getX(),nObj.getY(),nObj.getWidth(),nObj.getHeight());
                GUML g = SignalR.utworzObiekt(UMLType.NOTICE, p, nObj.guml.canvas, nObj.lines,false);
                Random r = new Random();
                ((Diagram.Notatka)g.obj_uml).Nazwa = "Obiekt " + r.Next(0, 666);
                nObj.guml.canvas.Children.Remove(g.panel);
                nObj.Refresh();
                return g.umlobj;
            }
            else if (getType() == typeof(AktorObj))
            {
                AktorObj aObj = this as AktorObj;
                Polozenie p = new Polozenie(aObj.getX(), aObj.getY(), aObj.getWidth(), aObj.getHeight());
                GUML g = SignalR.utworzObiekt(UMLType.ACTOR, p, aObj.guml.canvas, aObj.lines,false);
                Random r = new Random();
                ((Diagram.Aktor)g.obj_uml).Nazwa = "Obiekt "+r.Next(0,666);
                aObj.guml.canvas.Children.Remove(g.panel);
                aObj.Refresh();
                return g.umlobj;
            }
            else if (getType() == typeof(AssociationObj)) // ?
            {
            }
            else if (getType() == typeof(AkcjaObj))
            {
                AkcjaObj aObj = this as AkcjaObj;
                Polozenie p = new Polozenie(aObj.getX(), aObj.getY(), aObj.getWidth(), aObj.getHeight());
                GUML g = SignalR.utworzObiekt(UMLType.ACTION, p, aObj.guml.canvas, aObj.lines, false);
                Random r = new Random();
                ((Diagram.Akcja)g.obj_uml).Nazwa = "Obiekt " + r.Next(0, 666);
                aObj.guml.canvas.Children.Remove(g.panel);
                aObj.Refresh();
                return g.umlobj;
            }
            return null;
        }
        
    }

}
